﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using CodeDDD.Domain.Seedwork;
using CodeDDD.Infrastructure.Crosscutting.Seedwork.Logging;

namespace CodeDDD.Infrastructure.Data.EntityFramework
{
    public class Repository<TEntity, TIdentity> : IRepository<TEntity, TIdentity>
        where TEntity : Entity<TIdentity>
    {
        #region Members

        EFUnitOfWork _unitOfWork;

        IDbSet<TEntity> GetSet()
        {
            return _unitOfWork.CreateSet<TEntity>();
        }

        #endregion

        #region IRepository Members

        public Repository(EFUnitOfWork unitOfWork)
        {
            if (unitOfWork == null)
                throw new ArgumentNullException("unitOfWork");

            _unitOfWork = unitOfWork;
        }
        
        public IUnitOfWork UnitOfWork
        {
            get
            {
                return _unitOfWork;
            }
        }

        public IEnumerable<TEntity> GetAll()
        {
            return GetSet().AsEnumerable();
        }

        public TEntity Get(TIdentity id)
        {
            return GetSet().Find(id);
        }

        public void Add(TEntity item)
        {
            if (item != (TEntity)null)
            {
                GetSet().Add(item); // add new item in this set
            }
            else
            {
                //LoggerFactory.CreateLog()
                //          .LogInfo(Messages.info_CannotAddNullEntity, typeof(TEntity).ToString());
            }
        }

        public void Remove(TEntity item)
        {
            if (item != (TEntity)null)
            {
                // attach item if not exist
                _unitOfWork.Attach(item);

                // set as "removed"
                GetSet().Remove(item);
            }
            else
            {
                //LoggerFactory.CreateLog()
                //    .LogInfo(Messages.info_CannotRemoveNullEntity, typeof(TEntity).ToString());
            }
        }

        public void Update(TEntity item)
        {
            if (item != (TEntity)null)
            {
                _unitOfWork.SetModified(item);
            }
            else
            {
                //LoggerFactory.CreateLog()
                //          .LogInfo(Messages.info_CannotRemoveNullEntity, typeof(TEntity).ToString());
            }
        }

        #endregion

        #region IDisposable Members

        /// <summary>
        /// <see cref="M:System.IDisposable.Dispose"/>
        /// </summary>
        public void Dispose()
        {
            if (_unitOfWork != null)
                _unitOfWork.Dispose();
        }

        #endregion
    }
}
